package com.zuorenke.vertx.handler;

import com.zuorenke.help.HandlerUtils;
import com.zuorenke.help.ResponseUtils;
import com.zuorenke.help.TicketUtils;
import com.zuorenke.model.constants.CasCsts;
import com.zuorenke.model.constants.ExceptionCst;
import com.zuorenke.model.constants.LoginCst;
import com.zuorenke.vertx.config.RequestProperties;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
import io.vertx.core.Handler;
import io.vertx.core.http.HttpHeaders;
import io.vertx.ext.web.Cookie;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.impl.CookieImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Set;

import static io.vertx.core.http.HttpHeaders.COOKIE;
import static io.vertx.core.http.HttpHeaders.SET_COOKIE;

/**
 * @author Z.R.K
 * @description
 * @create 2019-05-16 17:55:54
 **/
@Component
@Slf4j
public class HeaderCheckHandler implements Handler<RoutingContext> {
	
	@Resource
	private RequestProperties requestProperties;
	
	@Override
	public void handle(RoutingContext ctx) {
		// check ContentLength
		String contentLength = ctx.request().getHeader(HttpHeaders.CONTENT_LENGTH);
		ctx.put(HttpHeaders.CONTENT_LENGTH.toString(), contentLength);
		if(contentLength != null){
			Long x = Long.parseLong(contentLength);
			Long maxContentLength = requestProperties.getHeaderMaxLength();
			if(x.compareTo(maxContentLength) > 0){
				log.warn("max content length is {}M!", maxContentLength / 1024 / 1024);
				ResponseUtils.responseErrorMsg(ctx.response(), HttpResponseStatus.LENGTH_REQUIRED);
				return ;
			}
		}
		
		// set cookie
		String cookieHeader = ctx.request().headers().get(COOKIE);
		
		if (cookieHeader != null) {
			Set<io.netty.handler.codec.http.cookie.Cookie> nettyCookies = ServerCookieDecoder.STRICT.decode(cookieHeader);
			for (io.netty.handler.codec.http.cookie.Cookie cookie : nettyCookies) {
				io.vertx.ext.web.Cookie ourCookie = new CookieImpl(cookie);
				ctx.addCookie(ourCookie);
			}
		}
		
		ctx.addHeadersEndHandler(v -> {
			Set<io.vertx.ext.web.Cookie> cookies = ctx.cookies();
			for (io.vertx.ext.web.Cookie cookie: cookies) {
				if (cookie.isChanged()) {
					ctx.response().headers().add(SET_COOKIE, cookie.encode());
				}
			}
		});
		
		// check ContentType
		String contentType = ctx.request().getHeader(HttpHeaders.CONTENT_TYPE);
		if(contentType != null && ctx.getBody() != null
				&& contentType.indexOf("multipart/form-data") > -1
				&& ctx.getBody().length() > 0){
			log.warn(" not support formdata upload file!");
			ResponseUtils.responseErrorMsg(ctx.response(), HttpResponseStatus.BAD_REQUEST);
			return ;
		}
		
		// check Ticket
		Cookie cookie = ctx.getCookie(CasCsts.TICKET);
		String ticket;
//		if(cookie == null){
//			ticket = ctx.request().getParam(CasCsts.TICKET);
//			if(ticket == null){
//				ResponseUtils.response500Msg(ctx.response(), ExceptionCst.NO_LOGIN);
//				return ;
//			}else{
//				if (!checkUser(ctx, ticket)) return;
//			}
//		}else{
//			if (!checkUser(ctx, cookie.getValue())) return;
//		}
		
		HandlerUtils.next(ctx);
	}
	
	private boolean checkUser(RoutingContext ctx, String ticket) {
		try{
			TicketUtils.getUserId(ticket);
			ctx.put(CasCsts.TICKET,ticket);
		}catch (Exception e){
			log.error(ExceptionCst.NO_LOGIN);
			ResponseUtils.response500Msg(ctx.response(), ExceptionCst.NO_LOGIN);
			return false;
		}
		return true;
	}
}